package com.zbkj.client.task;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zbkj.client.config.WebSocketSessionManager;
import com.zbkj.client.enums.WebSocketEventType;
import com.zbkj.client.service.AgentClientService;
import com.zbkj.client.service.ClientLoginService;
import com.zbkj.common.model.client.workbench.VideoSplit;
import com.zbkj.service.service.VideoSplitService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

@Slf4j
@Component
public class VideoSplitUpdateStatusTask {
    @Autowired
    private VideoSplitService videoSplitService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private WebSocketSessionManager webSocketSessionManager;

    @Autowired
    private AgentClientService agentClientService;

    @Autowired
    private ClientLoginService clientLoginService;

    @Autowired
    private ThreadPoolTaskScheduler taskScheduler;
    @Value("${workbench.video-split}")
    private String videoSplitBaseUrl;

    private final String videoSplitInfoUrl = "/api/v1/video/dismantle/status";
    private final ObjectMapper objectMapper = new ObjectMapper();

    public void start(String linkId) {
        scheduleTask(linkId, 0, 28);
    }

    private void scheduleTask(String linkId, int retry, int maxRetry) {
        long delay = retry == 0 ? 2 * 60 * 1000 : 60 * 1000; // 第一次2分钟，后面1分钟
        taskScheduler.schedule(() -> run(linkId, retry, maxRetry), new Date(System.currentTimeMillis() + delay));
    }

    private void run(String linkId, int retry, int maxRetry) {
        VideoSplit videoSplit = videoSplitService.getOne(new LambdaQueryWrapper<VideoSplit>().eq(VideoSplit::getLinkId, linkId));
        if (videoSplit == null) {
            log.warn("未找到视频拆解记录，linkId={}", linkId);
            return;
        }
        if (videoSplit.getIsDel() != null && videoSplit.getIsDel() == 1) {
            log.info("视频拆解记录已删除，linkId={}", linkId);
            return;
        }
        if (videoSplit.getStatus() != null && videoSplit.getStatus() != 1) {
            //扣点
            clientLoginService.updateMerPoint(videoSplit.getUserId(),
                    videoSplit.getMerId(),
                    "videoSplit",
                    videoSplit.getId(),
                    agentClientService.getMouleName("videoSplit"),
                    videoSplit.getTitle(),
                    agentClientService.getPointByDuration("videoSplit", videoSplit.getDuration()),
                    videoSplit.getDuration()
            );

            log.info("视频拆解状态已更新，linkId={}", linkId);
            return;
        }

        String url = videoSplitBaseUrl + videoSplitInfoUrl + "/" + linkId;
        try {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            JsonNode root = objectMapper.readTree(response.getBody());
            boolean success = root.path("success").asBoolean();
            JsonNode result = root.path("data");
            String taskStatus = result.path("taskStatus").asText();
            if (success && "SUCCESSED".equals(taskStatus)) {
                // 更新分析结果
                JsonNode videoAnalysisNode = result.path("videoAnalysisResult").path("video_analysis");
                String title = result.path("title").asText();
                String eventRes = result.path("event").asText();
                List<Map<String, Object>> videoAnalysis = objectMapper.convertValue(
                        videoAnalysisNode,
                        objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)
                );
                videoSplit.setVideoAnalysis(videoAnalysis);
                videoSplit.setTitle(title);

                // 确定事件名称
                String eventName="";

                if ("task-finished".equals(eventRes)){
                    //已完成
                    videoSplit.setStatus(2);
                    eventName = WebSocketEventType.AddVideoSplitSuccess.name();

                    //扣点
                    clientLoginService.updateMerPoint(videoSplit.getUserId(),
                            videoSplit.getMerId(),
                            "videoSplit",
                            videoSplit.getId(),
                            agentClientService.getMouleName("videoSplit"),
                            title,
                            agentClientService.getPointByDuration("videoSplit", videoSplit.getDuration()),
                            videoSplit.getDuration()
                    );

                }else if ("task-failed".equals(eventRes)){
                    //失败
                    videoSplit.setStatus(3);
                    String errMsg = result.path("errorMessage").asText();
                    videoSplit.setErrMsg(errMsg);
                    eventName = WebSocketEventType.AddVideoSplitFail.name();
                }

                videoSplit.setUpdateTime(new Date());
                videoSplitService.updateById(videoSplit);
                log.info("视频拆解任务完成，linkId={}", linkId);

                // 推送WebSocket消息给前端
                try {
                    Integer userId = videoSplit.getUserId();
                    if (userId != null) {
                        Map<String, Object> data = new HashMap<>();
                        data.put("id", videoSplit.getId());
                        data.put("linkId", videoSplit.getLinkId());
                        data.put("status", videoSplit.getStatus());

                        Map<String, Object> message = new HashMap<>();
                        message.put("event", eventName);
                        message.put("data", data);

                        String jsonMessage = JSON.toJSONString(message);
                        webSocketSessionManager.sendMessageToUser(userId, jsonMessage);
                        log.info("向用户 {} 推送视频拆解状态更新: {}", userId, jsonMessage);
                    }
                }catch (Exception e){
                    log.error("向用户 {} 推送视频拆解状态更新失败: {}", e.getMessage());
                }

            } else if (success && retry < maxRetry - 1) {
                log.info("视频拆解未完成，linkId={}, retry={}", linkId, retry + 1);
                scheduleTask(linkId, retry + 1, maxRetry);
            } else if(!success) {
                String message = root.path("message").asText();
                String errMsg = message != null ? message : "视频拆解失败";
                //失败
                videoSplit.setStatus(3);
                videoSplit.setErrMsg(errMsg);
                videoSplit.setUpdateTime(new Date());
                videoSplitService.updateById(videoSplit);

                String eventName = WebSocketEventType.AddVideoSplitFail.name();

                log.info("视频拆解任务失败，linkId={}", linkId);
            } else {
                videoSplit.setStatus(3);
                videoSplit.setErrMsg("视频拆解任务返回失败");
                videoSplit.setUpdateTime(new Date());
                videoSplitService.updateById(videoSplit);

                log.warn("视频拆解任务未完成或重试次数已达上限，linkId={}, retry={}", linkId, retry + 1);
            }
        } catch (Exception e) {
            videoSplit.setStatus(3);
            videoSplit.setErrMsg("视频拆解状态查询异常");
            videoSplit.setUpdateTime(new Date());
            videoSplitService.updateById(videoSplit);

            log.error("视频拆解状态查询异常，linkId={}", linkId, e);
        }
    }
} 